import { CustomEventSource } from './CustomEventSource'

/**
 * SSE事件类型定义
 */
interface SSEEvent {
  type: 'connected' | 'message'
  data: string
}

/**
 * API响应接口
 */
interface ApiResponse<T> {
  code: number
  message: string
  data: T
}

/**
 * 聊天服务类
 */
export class ChatService {
  private baseUrl: string
  private eventSource: CustomEventSource | null = null
  private emitterId: string | null = null
  private isConnecting: boolean = false
  private connectionPromise: Promise<void> | null = null

  constructor(baseUrl?: string) {
    this.baseUrl = 'http://localhost:8080/api/chat'
  }

  private getToken(): string | null {
    // 优先从 sessionStorage 获取，然后从 localStorage 获取
    return sessionStorage.getItem('token') || localStorage.getItem('token')
  }

  /**
   * 处理SSE连接响应
   */
  private handleConnectResponse(data: any) {
    if (data.code === 200 && data.data?.emitterId) {
      this.emitterId = data.data.emitterId
      console.log('SSE连接已建立, emitterId:', this.emitterId)
      return true
    }
    return false
  }

  /**
   * 清理文本内容
   */
  private cleanText(text: string): string {
    return text
      .replace(/\u200B/g, '') // 移除零宽空格
      .replace(/\u2022/g, '') // 移除项目符号 (•)
      .replace(/[\u0000-\u001F\u007F-\u009F]/g, '') // 移除控制字符
      .replace(/[\uFFF0-\uFFFF]/g, '') // 移除特殊Unicode字符
      .replace(/\uFEFF/g, '') // 移除BOM
      // 不使用trim()，保留首尾空白字符，以保持流式响应的格式
  }

  /**
   * 建立SSE连接
   */
  connect(callbacks: {
    onMessage: (content: string) => void
    onError?: (error: string) => void
  }): Promise<void> {
    console.log('Starting connect, current state:', {
      hasConnectionPromise: !!this.connectionPromise,
      hasEventSource: !!this.eventSource,
      emitterId: this.emitterId
    })

    if (this.connectionPromise) {
      return this.connectionPromise
    }

    this.connectionPromise = new Promise((resolve, reject) => {
      const token = this.getToken()
      if (!token) {
        const error = '未登录，请先登录'
        callbacks.onError?.(error)
        reject(new Error(error))
        return
      }

      const connectUrl = `${this.baseUrl}/connect`
      console.log('Connecting with token:', !!token)

      let timeoutId: number | null = null

      const eventSource = new CustomEventSource(connectUrl, {
        headers: {
          'Authorization': `Bearer ${token}`
        },
        withCredentials: true
      })

      this.eventSource = eventSource

      eventSource.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data)
          console.log('SSE message received (JSON):', data)
          
          if (data.code === 200) {
            if (data.data?.emitterId) {
              const connected = this.handleConnectResponse(data)
              if (connected && timeoutId) {
                clearTimeout(timeoutId)
                timeoutId = null
              }
              resolve()
            } else if (data.data?.message === 'SSE连接已建立') {
              console.log('SSE connection confirmed')
            } else if (typeof data.data === 'string') {
              // 处理服务器返回的消息内容
              callbacks.onMessage(this.cleanText(data.data))
            }
          } else if (data.type === 'message' && typeof data.data === 'string') {
            // 处理消息类型的事件
            callbacks.onMessage(this.cleanText(data.data))
          }
        } catch (error) {
          // 如果不是JSON格式，直接作为文本处理
          console.log('SSE message received (text):', event.data)
          callbacks.onMessage(this.cleanText(event.data))
        }
      }

      eventSource.onerror = (error) => {
        console.error('SSE connection error:', error)
        this.emitterId = null
        if (timeoutId) {
          clearTimeout(timeoutId)
          timeoutId = null
        }
        callbacks.onError?.('连接失败，请检查网络或重新登录')
        eventSource.close()
        reject(error)
      }

      // 延长超时时间
      timeoutId = window.setTimeout(() => {
        if (!this.emitterId) {
          const error = new Error('SSE connection timeout')
          console.error(error)
          eventSource.close()
          reject(error)
        }
      }, 30000) // 增加到30秒

      eventSource.connect()
    }).finally(() => {
      this.connectionPromise = null
    })

    return this.connectionPromise
  }

  /**
   * 检查连接状态
   */
  isConnected(): boolean {
    return this.emitterId !== null
  }

  /**
   * 断开SSE连接
   */
  disconnect() {
    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
      this.emitterId = null
    }
  }

  /**
   * 发送消息
   */
  async sendMessage(message: string, conversationId?: number) {
    console.log('Starting sendMessage:', {
      message,
      conversationId,
      token: !!this.getToken(),
      emitterId: this.emitterId
    })

    // 检查token
    if (!this.getToken()) {
      throw new Error('未登录，请先登录')
    }

    // 检查emitterId
    if (!this.emitterId) {
      console.error('No emitterId found, current state:', {
        eventSource: !!this.eventSource,
        connectionPromise: !!this.connectionPromise
      })
      throw new Error('SSE连接未建立，请稍后重试')
    }

    try {
      // 构建请求URL和参数
      let url = `${this.baseUrl}/send`
      const params = new URLSearchParams()
      
      // 添加必需的 emitterId
      params.append('emitterId', this.emitterId)
      
      // 如果是继续对话，添加 conversationId
      if (conversationId) {
        params.append('conversationId', conversationId.toString())
      }

      // 将参数添加到URL
      url = `${url}?${params.toString()}`

      console.log('Sending POST request:', {
        url,
        message,
        emitterId: this.emitterId,
        conversationId
      })

      // 发送请求
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${this.getToken()}`,
          'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({ message })
      })

      const data = await response.json()
      console.log('Send message response:', data)

      if (!response.ok || data.code !== 200) {
        throw new Error(data.message || 'Failed to send message')
      }

      return data.data
    } catch (error) {
      console.error('Send message failed:', error)
      throw error
    }
  }

  /**
   * 获取对话历史
   */
  async getHistory(conversationId: number) {
    // 检查token
    if (!this.getToken()) {
      throw new Error('未登录，请先登录')
    }

    const response = await fetch(`${this.baseUrl}/conversations/${conversationId}`, {
      headers: {
        'Authorization': `Bearer ${this.getToken()}`
      }
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const data = await response.json() as ApiResponse<Array<{
      role: 'system' | 'user' | 'assistant'
      content: string
    }>>

    if (data.code !== 200) {
      throw new Error(data.message)
    }

    return data.data
  }
}